home *** CD-ROM | disk | FTP | other *** search
- ;─────────────────────────────────────
- ;·▄▄▄ ▄▄▄· .▄▄ · ▄▄▄▄▄ ▄▄· ·▄▄▄▄
- ;▐▄▄· ▐█ ▀█ ▐█ ▀. ∙██ ▐█ ▌■ ██■ ██
- ;██■ ▄█▀▀█ ▄▀▀▀█▄ ▐█.■ ██ ▄▄ ▐█· ▐█
- ;██▌. ▐█ ■▐▌ ▐█▄■▐█ ▐█▌· ▐███▌ ██. ██
- ;▀▀▀ ▀ ▀ ▀▀▀▀ ▀▀▀ ·▀▀▀ ▀▀▀▀▀∙
- ;───────────────────────────────v0.9ß─
- ; A Tiny TSR CD Digital Audio Player
- ;├───────────────────────────────────┤
- ;∙ ■ Play·Stop·Skip·Volume functions ∙
- ;│ ■ Consumes 2000 bytes of memory │
- ;∙ ■ Full .ASM sources included ∙
- ;╘═══════════════════════════════════╛
-
- ; Author: Johan Prins
- ;Internet address: jprins@dmrt.nl
-
- CodeSg segment
- assume cs:codesg,ds:codesg
-
- BeginDump EQU $ ;Roy Silvernail - Keep TASM 1.0 happy
- ;when computing # resident paragraphs.
- ;
- org 2CH ;v0.01 ORG in PSP to pick up the
- envseg label word ;v0.01 Environment Segment.
- ;
- org 100h ;ORG for all COM programs.
- ;
- Entry PROC NEAR ;v0.01
- jmp TSRinit ;Jump over resident portion and
- ;initialize things and make code
- ;between Entry: and TSRinit: resident.
- ;
- oldint09 dd ? ;Keyboard Hardware Interrupt.
- oldint13 dd ? ;Disk BIOS Interrupt.
- oldint16 dd ? ;Keyboard BIOS Interrupt.
- oldint28 dd ? ;DOS Idle Interrupt.
- ;
- HOOK09 equ 09h ;Hooked Interrupt 09h.
- HOOK13 equ 13h ;Hooked Interrupt 13h.
- HOOK16 equ 16h ;Hooked Interrupt 16h.
- HOOK28 equ 28h ;Hooked Interrupt 28h.
- ;
- bellgate db 0 ;Gate closed (=1) when in Bell routine.
- ;Gate open (=0) when not in Bell routine.
-
- PICPORT EQU 20h ;I/O Port for the 8259A PIC chip.
- ISRREQ EQU 00001011B ;This is a byte defining the
- ;Operation Control Word 3 (OCW3) to
- ;output on port 20h to make the PIC
- ;chip's In Service Register available
- ;for reading by the CPU on the
- ;next IN 20h command.
-
- RSHIFT equ 00000001B ;Right Shift Key Flag weight.
- LSHIFT equ 00000010B ;Left Shift Key Flag weight.
- CTRL equ 00000100B ;Ctrl Key Flag weight.
- ALT equ 00001000B ;Alt Key Flag weight.
- ;SCROLL equ 00010000B ;Scroll Lock Key Flag weight.
- ;NUM equ 00100000B ;Num Lock Key Flag weight.
- ;CAPS equ 01000000B ;Caps Lock Key Flag weight.
- INSRT equ 10000000B ;Ins Key Flag weight.
- ;
- LockKeyMask equ 10001111B ;For masking out Scroll, Caps,
- ;and Num Lock bits in KeyFlags.
- indosptr dd ?
- criterrptr dd ?
- prtscrn dd 00500000h
- hotkeyflag db 0 ;hotkeyflag initially zero.
- diskflag db 0 ;diskflag initially zero.
-
- KEYFLAGBYTE equ CTRL+ALT ;HotKey Flags
- HOTKEY equ 21h ;'F' (for [F]astCD) key
-
- TSRsigA equ '■F' ;'FastCD' Signature
- TSRsigB equ 'as'
- TSRsigC equ 'tC'
- TSRsigD equ 'D■'
-
- Drive db ?
- Key dw ?
- data dd ?
- Tracks dd 30 dup (?)
- DEC8 dd ?
-
- old_bar db 104 dup (?)
-
- IOCTL db 13 dup (0) ;ReqHdr
- db 0 ;media descriptor byte
- dd ? ;transfer address
- dw ? ;bytes to transfer
- dw 0 ;starting sector
- dd 0 ;pointer to req. volume
-
- DiskInfo db 10 ;control block code
- db ? ;lowest track
- db ? ;highest track
- dd ? ;starting point of lead-out track
-
- TrakInfo db 11 ;control block code
- db ? ;Track number
- dd ? ;starting point of track
- db ? ;Track control info
-
- LocHead db 1 ;control block code
- db 0 ;addressing mode
- dd ? ;location of drivehead
-
- Play db 13 dup (0) ;request header
- db 1 ;addressing mode
- dd ? ;starting sector
- dd ? ;number of sector to play
-
- Stop db 13 dup(0) ;request header
-
- QInfo db 12 ;control block code
- db ? ;Control and ADR byte
- db ? ;Track #
- db ? ;point/index
- db ? ;Track min
- db ? ;Track sec
- db ? ;Track frame
- db ? ;Track zero
- db ? ;disk min
- db ? ;disk sec
- db ? ;disk frame
-
- AudInfo db 3 ;control block code
- db ? ;input channel for output channel 0
- db ? ;volume for output channel 0
- db ? ;input channel for output channel 1
- db ? ;volume for output channel 1
- db ? ;input channel for output channel 2
- db ? ;volume for output channel 2
- db ? ;input channel for output channel 3
- db ? ;volume for output channel 3
-
- BAR LABEL BYTE
- DB '█',3,'▓',115,'▒',115,'░'
- DB 115,' ',121,'F',117,'a',117,'s',117,'t',117,'C',117,'D'
- DB 117,' ',117,'▌',127,' ',127,'T',113,'r',113,'a',113,'c'
- DB 113,'k',113,':',113,' ',113,' ',113,' ',113,' ',113,'·'
- DB 113,' ',113,' ',113,' ',113,':',113,' ',113,' ',113,':'
- DB 113,' ',113,' ',113,' ',127,'▌',127,' ',127,'V',117,'o'
- DB 117,'l',117,':',117,' ',117,' ',117,' ',117,'∙',112,' '
- DB 117,' ',117,' ',117,'░',115,'▒',115,'▓',115,'█',115
-
- Entry ENDP ;v0.01
- ;
- ROUTINE PROC FAR
-
- ; Code for your HotKey-triggered TSR routine GOES HERE:
-
- assume cs:codesg,ds:codesg
-
- go:
- xor bx,bx
- mov ax,1500h
- int 2Fh ;Get Nr of CD-ROM drives
- mov Drive,cl ;CL contains 1st drive letter
-
- call getbar
- lea si,bar
- call putbar
-
- call GetAudInfo
- mov dl,AudInfo[2]
- shr dl,2
- mov si,112
- call dec8out
- mov dl,AudInfo[4]
- shr dl,2
- mov si,118
- call dec8out
-
- call GetDiskInfo ;Get # of tracks
- call GetDiskInfo ;Twice if first time failed...
-
- xor ch,ch
- mov cl,DiskInfo[2] ;Last track
- cmp cl,0 ;No tracks...exit
- jne Trks
- jmp exit
-
- Trks: call GetTrackInfo
- les ax,dword ptr TrakInfo[2]
- mov di,cx
- shl di,2
- mov word ptr Tracks[di+2],es
- mov word ptr Tracks[di],ax
- loop Trks
-
- call GetAudInfo
-
- no_key:
- call QChannelInfo
- mov al,QInfo[2] ;contains track nr. as it appears on CD
- ;AL needs conversion:
- mov dl,al
- and dl,000001111b ;save low nibble
- and al,011110000b ;save high nibble
- shr al,4
- mov bl,0Ah
- mul bl ;multiply high nibble by 10
- add dl,al
- xor dh,dh
- mov di,dx
- mov si,70
- call dec8out
- mov dl,QInfo[4]
- mov si,80
- call dec8out
- mov dl,QInfo[5]
- mov si,86
- call dec8out
- mov dl,QInfo[6]
- mov si,92
- call dec8out
-
- mov ah,01h
- int 16h
- jz no_key ;keypressed?
- xor ah,ah
- int 16h
- mov key,ax ;read scancode and char
-
- cmp ah,19h ; P or p (play)
- jne Key_S
- mov di,1
- call StopCD
- call PlayCD
- jmp no_key
-
- Key_S: cmp ah,1Fh ;S or s (stop)
- jne KeyPgUp
- call StopCD
- jmp no_key
-
- KeyPgUp:cmp ax,4900h ;PgUp (skip to next track)
- jne KeyPgDn
- xor cx,cx
- mov cl,byte ptr DiskInfo[2]
- cmp cx,di
- jne nomax
- mov di,0
- nomax: inc di
- call StopCD
- call PlayCD
- jmp no_key
-
- KeyPgDn:cmp ax,5100h ;PgDn (skip to prev. track)
- jne Key_Up
- cmp di,1
- jne nomin
- mov cx,0001
- add cl,byte ptr DiskInfo[2]
- mov di,cx
- nomin: dec di
- call StopCD
- call PlayCD
- jmp no_key
-
- Key_Up: cmp ax,4800h
- jne Key_Dn
- add AudInfo[2],4
- add AudInfo[4],4
- call PutAudInfo
- mov dl,AudInfo[2]
- shr dl,2
- mov si,112
- call dec8out
- mov dl,AudInfo[4]
- shr dl,2
- mov si,118
- call dec8out
- jmp no_key
-
- Key_Dn: cmp ax,5000h
- jne Key_Lf
- sub AudInfo[2],4
- sub AudInfo[4],4
- call PutAudInfo
- mov dl,AudInfo[2]
- shr dl,2
- mov si,112
- call dec8out
- mov dl,AudInfo[4]
- shr dl,2
- mov si,118
- call dec8out
- jmp no_key
-
- Key_Lf: cmp ax,4B00h
- jne Key_Rg
- sub AudInfo[4],4
- call PutAudInfo
- mov dl,AudInfo[4]
- shr dl,2
- mov si,118
- call dec8out
- jmp no_key
-
- Key_Rg: cmp ax,4D00h
- jne Key_ESC
- sub AudInfo[2],4
- call PutAudInfo
- mov dl,AudInfo[2]
- shr dl,2
- mov si,112
- call dec8out
- jmp no_key
-
- Key_ESC:cmp ax,011Bh ;ESC (exit program)
- je xit
- jmp no_key
- xit: jmp exit
-
- ToCD proc
- push ax
- push bx
- push cx
- mov ax,1510h
- xor ch,ch
- mov cl,Drive
- les bx,data
- int 2Fh
- pop cx
- pop bx
- pop ax
- ret
- endp ToCD
-
- GetDiskInfo proc
- mov IOCTL[2],3 ;Command code
-
- mov ax,cs
- mov word ptr IOCTL[16],ax ;transfer address
- mov ax,offset DiskInfo
- mov word ptr IOCTL[14],ax ;transfer address
-
- mov IOCTL[18],7 ;bytes to transfer
-
- mov ax,cs
- mov word ptr data[2],ax ;address of IOCTL record
- mov ax,offset IOCTL
- mov word ptr data,ax ;address of IOCTL record
-
- call ToCD ; Diskinfo[1,2] contains 1st & last trk
-
- xor bx,bx
- mov bl, byte ptr DiskInfo[2]
- mov di,bx
- inc di
- shl di,2
- les ax,dword ptr DiskInfo[3]
- mov word ptr Tracks[di+2],es ;end of disc
- mov word ptr Tracks[di],ax
- ret
-
- endp GetDiskInfo
-
- GetTrackInfo proc
- mov IOCTL[2],3 ;command code
-
- mov ax,cs
- mov word ptr IOCTL[16],ax ;transfer address
- mov ax,offset TrakInfo
- mov word ptr IOCTL[14],ax ;transfer address
-
- mov IOCTL[18],7
-
- mov TrakInfo[1],cl ;contains track number
-
- mov ax,cs
- mov word ptr data[2],ax ;address of IOCTL record
- mov ax,offset IOCTL
- mov word ptr data,ax
-
- call ToCD
- ret
- endp GetTrackInfo
-
- PutAudInfo proc ;DL=left, DH=right volume
- mov IOCTL[2],12 ;command code
-
- mov ax,cs
- mov word ptr IOCTL[16],ax ;transfer address
- mov ax,offset AudInfo
- mov word ptr IOCTL[14],ax ;transfer address
-
- mov IOCTL[18],9
-
- mov ax,cs
- mov word ptr data[2],ax ;address of IOCTL record
- mov ax,offset IOCTL
- mov word ptr data,ax
-
- call ToCD
- ret
- endp PutAudInfo
-
- GetAudInfo proc
- mov IOCTL[2],3 ;command code
- inc AudInfo[0]
-
- mov ax,cs
- mov word ptr IOCTL[16],ax ;transfer address
- mov ax,offset AudInfo
- mov word ptr IOCTL[14],ax ;transfer address
-
- mov IOCTL[18],9
-
- mov ax,cs
- mov word ptr data[2],ax ;address of IOCTL record
- mov ax,offset IOCTL
- mov word ptr data,ax
-
- call ToCD
- dec AudInfo[0]
- ret
- endp GetAudInfo
-
-
- PlayCD proc ;DI must contain track number
- push di
- mov Play[2],132 ;command code
-
- shl di,2
-
- les bx,dword ptr Tracks[di]
- mov word ptr Play[16],es
- mov word ptr Play[14],bx
- mov cx,es
-
- call RedBook2HSG
- mov bx,ax
- mov cx,dx
- push bx
- push cx
-
- mov al,DiskInfo[2] ;begin of last track
- inc al
- xor ah,ah
- shl ax,2 ;it are dwords
- mov di,ax
-
- call RedBook2HSG
-
- pop cx
- pop bx
-
- sub ax,bx
- jnc @1
- dec dx
- @1: sub dx,cx
-
- mov word ptr Play[20],dx
- mov word ptr Play[18],ax
-
- mov ax,cs
- mov word ptr data[2],ax ;address of Play record
- mov ax,offset Play
- mov word ptr data,ax
-
- call ToCD
-
- pop di
- ret
- endp PlayCD
-
- QChannelInfo proc
- mov IOCTL[2],3 ;command code
-
- mov ax,cs
- mov word ptr IOCTL[16],ax ;transfer address
- mov ax,offset QInfo
- mov word ptr IOCTL[14],ax ;transfer address
-
- mov IOCTL[18],11
-
- mov ax,cs
- mov word ptr data[2],ax ;address of IOCTL record
- mov ax,offset IOCTL
- mov word ptr data,ax
-
- call ToCD
- ret
- endp QChannelInfo
-
-
- StopCD proc
- mov Stop[2],133 ;command code
-
- mov ax,cs
- mov word ptr data[2],ax ;address of Stop record
- mov ax,offset Stop
- mov word ptr data,ax
-
- call ToCD
-
- ret
- endp StopCD
-
-
- RedBook2HSG proc
-
- mov ax,word ptr Tracks[di+2] ;get high word
- mov cx,4500
- mul cx
-
- push ax ;put ax aside
-
- mov al,byte ptr Tracks[di+1]
- mov cl,75
- mul cl
- mov bx,ax
-
- pop ax ;get ax back
-
- add ax,bx
- jnc @2 ;carry? then decrease high word
- inc dx
- @2: mov cl,byte ptr Tracks[di]
- xor ch,ch
- add ax,cx
- jnc @3
- inc dx
- @3: sub ax,150
- jnc @4
- dec dx
- @4:
- ret
- endp RedBook2HSG
-
- dec8out proc
-
- push di
- push ds
- mov bx,0B800h
- mov ds,bx
- xor cx,cx ; initialize a counter
- mov di,1 ; point to a buffer
- mov byte ptr cs:DEC8[1],'0' ; zero unused var's
- mov byte ptr cs:DEC8[2],'0' ; " " "
- mov byte ptr cs:DEC8[3],'0' ; " " "
-
- dec8out1:
- push cx ; save the count
- mov al,dl ; AX has the numerator
- xor ah,ah ; clear upper half
- mov cl,10 ; divisor of 10
- div cl ; divide
- mov dl,al ; get quotient
- mov al,ah ; get remainder
- add al,30h ; increase to ASCII
- mov byte ptr cs:DEC8[di],al; put in tbuff
- inc di ; point to next byte
-
- pop cx ; restore count
- inc cx ; count the digit
- cmp dl,0 ; done ?
- jnz dec8out1
-
- mov al,byte ptr cs:DEC8[2]
- mov ds:[si],al
- mov al,byte ptr cs:DEC8[1]
- mov ds:[si+2],al
-
- pop ds
- pop di
-
- ret ; return
- dec8out endp
-
-
- putbar proc
- push di
- push ds
- cld
- mov dx,cs
- mov ds,dx
- mov dx,0B800h
- mov es,dx
-
- mov di,28
- mov cx,104
- rep movsb
-
- pop ds
- pop di
-
- ret
- putbar endp
-
- getbar proc
- push di
- push ds
-
- cld
- mov dx,cs
- mov es,dx
- mov dx,0B800h
- mov ds,dx
- mov si,28
- lea di,old_bar
- mov cx,104
- rep movsb
-
- pop ds
- pop di
-
- ret
- getbar endp
-
- exit: lea si,old_bar
- call putbar
-
- ret ;Return from TSR routine.
- ;
- ROUTINE endp
- ;
- ; End of your HotKeyed TSR routine.
-
- NewInt09 PROC FAR ;v0.01
- ;
- pushf ;Push flags as a true interrupt would.
- cli ;Be sure interrupts are disabled.
- call CS:oldint09 ;Call FAR PTR address of old interrupt
- ; ; handler routine.
- push ax ;Prepare to check for Hotkey.
- push bx ;Save all registers (DS is already pushed).
- push cx
- push dx
- push si
- push di
- push bp
- push ds
- push es
- ;
- push CS ;Set up data segment
- pop DS ;register to point to code segment.
- ;
- ASSUME DS:codesg ;v0.01
- ;
- in al,60h ;Get current Key Scan Code.
- cmp al,HOTKEY ;Is it HotKey's Scan Code?
- jne Exit09 ;Exit if not.
- mov ah,02h ;Int16h,Fcn02h:GetKEYFLAGBYTE.
- Int 16h ;Return Key Flag Byte in al.
- and al,LockKeyMask ;Mask out Num, Caps, Scroll Lock bits.
- cmp al,KEYFLAGBYTE ;Are the HotKey Flags active ?
- jne Exit09 ;Exit if not.
- ;
- ClrKbdBuf: ;Clear Keyboard buffer:
- mov ah,01h ;Get Keyboard buffer status
- int 16h ;via BIOS Interrupt 16h.
- jz BufClr ;Jump if buffer empty.
- mov ah,00h ;Get key from buffer (to purge it)
- int 16h ;via BIOS Interrupt 16h.
- jmp ClrKbdBuf ;Loop back to purge another key.
- BufClr:
- ;
- cmp bellgate,0 ;Is it clear to re-enter Hotkey code?
- jne BusyExit09 ;Exit if not,
- mov bellgate,1 ;Else, close gate and proceed.
- ;
- CLI ;DISABLE INTERRUPTS
-
- HotKeyPressed:
- mov al,ISRREQ ;al=PIC's OCW3 to ask for ISR Register.
- out PICPORT,al ;Tell PIC to get ISR ready for reading.
- jmp Dally ;Give PIC time to make ISR available.
- Dally: in al,PICPORT ;Fetch the ISR Register from PIC.
- or al,al ;Activate processor flags.
- jnz setflg ;If al not zero, go set flag.
- ;
- HotKeyNoHWI:
- les bx,indosptr ;es:bx = pointer to InDOS flag
- mov al,es:[bx] ;al = InDOS flag.
- or al,al ;Activate processor flags.
- jnz setflg ;Jump if InDOS not zero.
-
- les bx,criterrptr ;es:bx = pointer to CritErr flag.
- mov al,es:[bx] ;al = CritErr flag.
-
- or al,diskflag ;al = CritErr | diskflag
- ; (| => Logical OR).
- jnz Exit09 ;If al not zero, try again later.
-
- les bx,prtscrn ;ES:bx = pointer to PrtScrn busy flag.
- cmp BYTE PTR es:[bx],1 ;Is PrtScrn in progress?
- je Exit09 ;If so, try again later.
- ;
- STI ;Allow other interrupts in our TSR.
- ;
- call ROUTINE ;All is clear!, so call routine.
- mov hotkeyflag,0 ;Be sure HotKey flag is reset.
- jmp SHORT Exit09 ;Exit after TSR routine.
- ;
- setflg:
- mov hotkeyflag,1 ;Set HotKey Flag for use by Int28h.
- ;
- Exit09:
- mov CS:bellgate,0 ;Open gate allowing new HotKey detect.
- BusyExit09:
- pop es ;Restore all registers
- pop ds
- ASSUME DS:NOTHING ;v0.01
- pop bp
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ;
- iret
- ;
- NewInt09 ENDP ;v0.01
- ;
- NewInt13 PROC FAR ;We hook Int13h only for purpose
- ;of setting a flag to prevent our
- ;TSR from triggering during time-
- ;critical Disk accesses.
- mov CS:diskflag,1 ;Set flag to show Disk access.
- ;
- pushf ;Invoke prior Int13 handler
- cli ;(be sure interrupts disabled)
- call CS:oldint13 ;by simulating an interrupt.
- ;
- mov CS:diskflag,0 ;Clear flag to show Disk finished.
- ;
- RET 2 ;Return from interrupt while
- ;preserving flags.
- ;
- NewInt13 ENDP
-
- NewInt16 PROC FAR ;v0.01
- ;
- push ds ;Entry for New Int. Handler.
- ; ;Save required registers.
- ;
- push CS ;Set data seg v0.01
- pop DS ;to our codesg v0.01
- ASSUME DS:codesg ;v0.01
- ;
- cmp ax,TSRsigA ;Is ax = TSR signature word A?
- jne Exit16 ;No, let regular Int16 handle this.
- cmp bx,TSRsigB ;Is bx = TSR signature word B?
- jne Exit16 ;No, let regular Int16 handle this.
- cmp cx,TSRsigC ;Is cx = TSR signature word C?
- jne Exit16 ;No, let regular Int16 handle this.
- cmp dx,TSRsigD ;Is dx = TSR signature word D?
- jne Exit16 ;No, let regular Int16 handle this.
- ;
- xchg bx,cx ;Exchange regs. (DOS Int16h wouldn't do this)
- xchg ax,dx ; " " "
- ;
- pop ds ;Restore regs.
- iret ;Return from Int to TSR Initialize routine.
- ;
- Exit16:
- pop ds ;Restore all registers
- ASSUME DS:NOTHING ;v0.01
- ;
- jmp CS:oldint16
- ;
- NewInt16 ENDP ;v0.01
-
- NewInt28 PROC FAR ;v0.01
- ;
- pushf ;Call prior handler.
- cli
- call CS:oldint28
- ;
- cmp CS:hotkeyflag,1 ;Has HotKey been pressed?
- jne QuickExit ;Exit if not.
- ;
- cmp CS:bellgate,1 ;Is gate closed?
- je QuickExit ;If so, exit.
- mov CS:bellgate,1 ;Else close gate and proceed.
- ;
- CLI ;DISABLE INTERRUPTS
-
- push ax ;Entry for New Int. Handler.
- push bx ;Save all registers.
- push cx
- push dx
- push si
- push di
- push bp
- push ds
- push es
- ;
- push CS
- pop DS
- ASSUME DS:codesg ;v0.01
- ;
- les bx,indosptr ;ES:bx points to InDOS flag.
- cmp BYTE PTR ES:[bx],1 ;Is InDOS flag above 1?
- ja Exit28 ;Exit if InDOS > 1.
- ;
- HotKeyPressed2:
- mov al,ISRREQ ;al=PIC's OCW3 to ask for ISR Register.
- out PICPORT,al ;Tell PIC to get ISR ready for reading.
- jmp Dally2 ;Give PIC time to make ISR available.
- Dally2: in al,PICPORT ;Fetch the ISR Register from PIC.
- ;
- or al,diskflag ;al = ISR | diskflag. (| => Logical OR).
- jnz Exit28 ;If al not zero, try again later.
- ;
- les bx,prtscrn ;ES:bx = pointer to PrtScrn busy flag.
- cmp BYTE PTR es:[bx],1 ;Is PrtScrn in progress?
- je Exit28 ;If so, Exit w/o triggering TSR.
- ;
- STI ;ENABLE OTHER INTERRUPTS.
- ;
- HotKeyFlagSet:
- ;
- call ROUTINE ;Call TSR routine; DOSOK & No Hardware
- ;interrupts being serviced.
- mov CS:hotkeyflag,0 ;Clear HotKey Flag.
- ;
- Exit28:
- pop es ;Restore all registers
- pop ds
- ASSUME ds:NOTHING
- pop bp
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- mov CS:bellgate,0
- ;
- QuickExit:
- iret
- ;
- NewInt28 ENDP ;v0.01
- ; -END OF TSR's RESIDENT CODE-
-
- ; BEGINNING OF TSR's INITIALIZATION CODE (THE "BOOSTER"):
- ;
- TSRinit PROC NEAR ;v0.01
- EndDump EQU $
-
- xor bx,bx
- mov ax,1500h
- int 2Fh ;Get Nr of CD-ROM drives
- cmp bx,0 ;Nr of CD-ROM drives
- jz NoMSCD ;0 -> driver not installed
- jmp DosCHK
- NoMSCD: mov dx,OFFSET NoMSCDEX
- mov ah,09h
- int 21h
- mov ax,4C00h
- int 21h
- ;
- DosCHK: mov ah,30h ;Fcn 30h = Get DOS Version
- int 21h ;DOS Version = al.ah
- ;
- cmp al,1 ;Is this DOS Version 1.x?
- ja DOSverOK ;If not, DOS version is OK.
- push bx ;A "push" for the "pop" at DOSver1 label.
- jmp DOSver1 ;If so, TSR won't work so exit.
- ;
- DOSverOK:
- mov ax,TSRsigA ;Prime registers for our
- mov bx,TSRsigB ;Int16h handler's check
- mov cx,TSRsigC ;for prior installation
- mov dx,TSRsigD ;thru TSR signature words.
- ;
- Int 16h ;Check prior installation.
- ;
- cmp ax,TSRsigD ;Was TSR signature detected?
- jne Install ;If not, Install it.
- cmp bx,TSRsigC
- jne Install
- cmp cx,TSRsigB
- jne Install
- cmp dx,TSRsigA
- jne Install
-
- mov dx,Offset PriorInstMsg ;DX points to message.
- mov ah,09h ;DOS Fcn. 09h=Display String.
- Int 21h ;Display String via DOS.
- ;
- mov ax,4C00h ;Fcn 4C = DOS Terminate call
- Int 21h ;Do it.
- ;
- Install:
- ;
- ;Get segment of Environment
- ;from 02Ch in the Program
- ;Segment Prefix (PSP).
- ;
- mov ES,envseg ;ES=PSP's environ seg v0.01
- mov ah,49h ;DOS Fcn 49h = Release Memory
- int 21h ;Release it via DOS interrupt.
- ;
- ; Allocate the memory needed by the tiny 'Pseudo-Environment":
-
- mov bx,1 ;Allocate one parag. (16bytes)
- mov ah,48h ;and return allocation
- int 21h ;segment in ax via DOS call.
- ;
- mov ES,ax ;Pseudo-Env. Segment to ES.
- mov si,OFFSET PseudoEnv ;si=source string OFFSET.
- mov di,0 ;di=destination string OFFSET.
- mov cx,ENVLNGTH ;cx=Bytes in Pseudo-Env.string.
- cld ;Forward string move direction.
- rep movsb ;Move Pseudo-Env. string @ DS:si to ES:di
- ;
- mov envseg,ES
- ;
- mov ax,3500H+HOOK09 ;Get old Int 9 vector v0.01
- int 21h ;Int.Vector in ES:BX via DOS.
- mov Word Ptr oldint09,bx ;Save Offset of Old Interrupt.
- mov word ptr oldint09+2,ES ;save seg v0.01
- mov ax,2500H+HOOK09 ;Set new Int 9 vector v0.01
- mov dx,Offset NewInt09 ;dx=Offset of New Int Handler.
- int 21h ;Set New Int via DOS.
-
- mov ax,3500H+HOOK13 ;Get old Int 13 vector
- int 21h ;Int.Vector in ES:BX via DOS.
- mov Word Ptr oldint13,bx ;Save Offset of Old Interrupt.
- mov word ptr oldint13+2,ES ;save Segment.
- mov ax,2500H+HOOK13 ;Set new Int 13 vector.
- mov dx,Offset NewInt13 ;dx=Offset of New Int Handler.
- int 21h ;Set New Int via DOS.
-
- mov ax,3500H+HOOK16 ;get old Int 16H vector v0.01
- int 21h ;Int.Vector in ES:BX via DOS.
- mov Word Ptr oldint16,bx ;Save Offset of Old Interrupt.
- mov word ptr oldint16+2,ES ;save segment v0.01
- mov ax,2500H+HOOK16 ;set new Int 16H vector v0.01
- mov dx,Offset NewInt16 ;dx=Offset of New Int Handler.
- int 21h ;Set New Int via DOS.
-
- mov ax,3500H+HOOK28 ;Get old Int 28H vector v0.01
- int 21h ;Int.Vector in ES:BX via DOS.
- mov Word Ptr oldint28,bx ;Save Offset of Old Interrupt.
- mov word ptr oldint28+2,ES ;save segment v0.01
- mov ax,2500H+HOOK28 ;set new Int 28H vector v0.01
- mov dx,Offset NewInt28 ;dx=Offset of New Int Handler.
- int 21h ;Set New Int via DOS.
- mov ah,34h ;DOS FCN=34h:Get InDOS Pointer.
- int 21h ;Pointer in ES:BX
- mov Word Ptr indosptr,bx ;Save Offset of InDOS flag.
- mov Word Ptr indosptr+2,ES ;Save Segment of InDOS flag.
- ;
- mov Word Ptr criterrptr+2,ES ;Also, Seg of CritErr flag.
- push bx ;Save indosptr on stack for use below.
-
- mov ah,30h ;Fcn 30h = Get DOS Version
- int 21h ;DOS Version = al.ah
-
- cmp al,2 ;Is it DOS Version 2.x?
- je DOSver2 ;If yes, jump;
- ja DOSver3 ;or, if later version, jump;
- ;else, it's DOS Version 1.x:
- ;
- DOSver1: ;If here, DOS Version 1.x is being run:
- mov dx,OFFSET BailOutMsg ;TBONES needs DOS 2.x or later.
- mov ah,09h ;Say we're sorry, but NO GO
- int 21h ;via DOS.
- pop bx ;Clear stack.
- int 20h ;Terminate without installing
- ;in only way DOS 1.x knows.
- ;
- DOSver2: ;If here, DOS Version 2.x is being run:
- pop bx ;Get indosptr from stack.
- inc bx ;CritErr flag is @ indosptr+1.
- mov Word Ptr criterrptr,bx ;Save CritErr Pointer.
- jmp Announce ;Go announce TSR installed.
- ;
- DOSver3: ;If here, DOS Version 3.+ is being run:
- pop bx ;Get indosptr from stack.
- dec bx ;CritErr flag is @ indosptr-1.
- mov Word Ptr criterrptr,bx ;Save CritErr Pointer.
- ;
- Announce:
- mov dx,Offset InstallMsg ;DX points to message.
- mov ah,09h ;DOS Fcn. 09h=Display String.
- int 21h ;Display String via DOS.
- ;
- mov dx,(EndDump-BeginDump+0Fh)/16
- mov ah,31h ;DOS FCN 31h=TSR Call.
- int 21h ;Go Resident via DOS TSR call.
- ;
- PseudoEnv: DB ' ',0,0,1,0,'■FastCD■',0
- ENVLNGTH EQU $-PseudoEnv
- ;
-
-
- NoMSCDEX:
- db 'FastCD requires MSCDEX.EXE',0Dh,0Ah,'$'
-
-
- BailOutMsg:
- db 0Dh,0Ah
- db 'Sorry. FastCD requires DOS v2.0 or better'
- db 0Dh,0Ah,'$'
- PriorInstMsg:
- db 0Dh,0Ah
- db 'FastCD is already installed'
- InstallMsg:
- db 0Dh,0Ah
- db 'Use Ctrl-Alt-F to activate program'
- db 0Dh,0Ah
- db 0Dh,0Ah
- db 'FastCD v0.9ß ∙ A TSR Digital Audio CD Player'
- db 0Dh,0Ah
- db 'Copyright (C) 1995 by Johan Prins'
- db 0Dh,0Ah,'$'
- ;
- TSRinit ENDP ;v0.01
-
- codesg ends
- end Entry